﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;

namespace Raider.WinForms.Actions
{
    /// <summary>
    /// Represents a set of the unique actions with the support of
    /// data binding.
    /// </summary>
    class ActionCollection : BindingList<IAction>
    {
        protected override void InsertItem(int index, IAction item)
        {
            if (!Contains(item))
            {
                base.InsertItem(index, item);
                item.PropertyChanged += ItemPropertyChanged;
                item.Disposed += ItemDisposed;
            }
        }

        protected override void SetItem(int index, IAction item)
        {
            if (item != null && item != this[index])
            {
                var otherIndex = IndexOf(item);
                if (otherIndex >= 0 && this[otherIndex] != null)
                {
                    this[otherIndex].PropertyChanged -= ItemPropertyChanged;
                    this[otherIndex].Disposed -= ItemDisposed;
                    this[otherIndex] = null;
                }

                base.SetItem(index, item);
                item.PropertyChanged += ItemPropertyChanged;
                item.Disposed += ItemDisposed;
            }
        }

        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            OnListChanged(new ListChangedEventArgs(
                ListChangedType.ItemChanged, IndexOf((IAction)sender)));
        }

        private void ItemDisposed(object sender, EventArgs e)
        {
            Remove((IAction)sender);
        }

        protected override void RemoveItem(int index)
        {
            this[index].PropertyChanged -= ItemPropertyChanged;
            this[index].Disposed -= ItemDisposed;
            base.RemoveItem(index);
        }

        protected override void ClearItems()
        {
            foreach (var action in this)
            {
                action.PropertyChanged -= ItemPropertyChanged;
                action.Disposed -= ItemDisposed;
            }

            base.ClearItems();
        }
    }
}
